<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js异步加载</title>



<!--
    1、defer 异步加载。系统读到这里不会阻塞html css加载。要等到整个文档解析完才能执行
-->
    <!--  defer 异步加载  -->
<!--    <script src="tools.js" defer></script>-->
<!--    <script defer>-->
<!--        //还可以写在这里，代码块也变成异步下载-->
<!--    </script>-->

<!--
2、async （asychronous） 异步加载。w3c 标准，只能加载外部脚本
// asychronous javascript xml  ajax缩写
-->
    <!--  async 异步加载  -->
<!--    <script src="tools.js" async="async"></script>-->


<!--  浏览器兼容  -->
<!--    <script src="tools.js" defer="defer"></script>-->
<!--    <script src="tools.js" async="async"></script>-->
<!--  行不通  -->


<!--  所以只能用第三种方法  -->
<!--  3.创建script 插入到DOM中 加载完毕后callback  -->



</head>
<body>

<script>
/*
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "tools.js";//执行到里  会把tools.js 下载，但不会执行tools.js里面的js代码
    document.head.appendChild(script);//插入到头部去，才回去解析这个脚本
    //test();//直接执行会报错？//因为执行到这里，tools.js文件还没有下载结束（存在可能）

    //????那什么时候可以执行呢？ 怎么提示js文件下载完成呢？

    //1.可以使用onload
    script.onload = function () {//兼容性强大
        test();
    };

    //2.ie中的readyState 和 onreadystatechange  = function (){} 来监测

    script.readyState = "loading";//loading 是刚开始的值，readyState的值会随着文件加载的进度改变而改变
    //script.readyState = "loaded";//加载完成

    script.onreadystatechange = function () {//监听加载状态的方法，改变一次触发一次
        if(script.readyState == "complete" || script.readyState == "loaded"){
            test();
        }
    }
*/

</script>
<script>
    /*

    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "tools.js";
    if(script.readyState){
        script.onreadystatechange = function () {
            if(script.readyState == "complete" || script.readyState == "loaded"){
                test();
            }
        }
    }else {
        script.onload = function () {
            test();
        };
    }
    document.head.appendChild(script);

     */
</script>



<!--封装一个函数 党要加载异步一个script的时候-->
<script>
    /*

    function loadScript(url,callback) {//url要加载的js文件，callback回调函数（指需要执行的方法）
        var script = document.createElement("script");
        script.type = "text/javascript";
        // script.src = url;//这行代码不能绑定在这里，如果它一来就加载问了，就不会
        // 触发script.onreadystatechange 和 script.onload 两事件，所以得把它放到后面
        if(script.readyState){
            script.onreadystatechange = function () {
                if(script.readyState == "complete" || script.readyState == "loaded"){
                    callback();
                }
            }
        }else {
            script.onload = function () {
                callback();
            };
        }
        script.src = url;
        document.head.appendChild(script);
    }
    // 调用
   //loadScript("tools.js",test);//报错，执行到这里浏览器会解析test
    loadScript("tools.js",function () {
        test();
    })
    //按需加载

     */
</script>

<!--用eval()-->
<script>
/*
    function loadScript(url,callback) {//url要加载的js文件，callback回调函数（指需要执行的方法）
        var script = document.createElement("script");
        script.type = "text/javascript";
        // script.src = url;//这行代码不能绑定在这里，如果它一来就加载问了，就不会
        // 触发script.onreadystatechange 和 script.onload 两事件，所以得把它放到后面
        if(script.readyState){
            script.onreadystatechange = function () {
                if(script.readyState == "complete" || script.readyState == "loaded"){
                    eval(callback);
                }
            }
        }else {
            script.onload = function () {
                eval(callback);
            };
        }
        script.src = url;
        document.head.appendChild(script);
    }
    // 调用
    //loadScript("tools.js",test);//报错，执行到这里浏览器会解析test
    loadScript("tools.js","test()")
*/
</script>


<!--另一种方法-->
<script>
    //在tools.js键一个函数功能的一个对象叫 eval(callback);
    function loadScript(url,callback) {//url要加载的js文件，callback回调函数（指需要执行的方法）
        var script = document.createElement("script");
        script.type = "text/javascript";
        // script.src = url;//这行代码不能绑定在这里，如果它一来就加载问了，就不会
        // 触发script.onreadystatechange 和 script.onload 两事件，所以得把它放到后面
        if(script.readyState){
            script.onreadystatechange = function () {
                if(script.readyState == "complete" || script.readyState == "loaded"){
                    objTools[callback]();
                }
            }
        }else {
            script.onload = function () {
                objTools[callback]();
            };
        }
        script.src = url;
        document.head.appendChild(script);
    }
    // 调用
    //loadScript("tools.js",test);//报错，执行到这里浏览器会解析test
    loadScript("tools.js","test")
</script>
</body>
</html>
